package com.dk.controller;

import com.alibaba.fastjson.JSON;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import com.dk.data.Result;
import com.dk.em.ConstantEnum;
import com.dk.entity.TAdmin;
import com.dk.exception.LoginException;
import com.dk.mapper.TAdminMapper;
import com.dk.service.ITAdminService;
import com.dk.util.ShiroUtils;
import io.swagger.annotations.*;
import org.apache.rocketmq.spring.core.RocketMQTemplate;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.*;

import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author author
 * @since 2021-10-29
 */
@RestController
@RequestMapping("/admin")
@Api(value = "前台登录注册功能接口")
public class TAdminController {

    @Autowired
    private ITAdminService adminService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private RocketMQTemplate rocketMQTemplate;

     @Autowired
     private TAdminMapper adminMapper;

    @ApiOperation(value = "注册手机号发短息")
    @ApiImplicitParams({
            @ApiImplicitParam(name="phone",value = "手机号",required = true,paramType = "query")
    })
    @PostMapping("code")
    public Result code(String phone){
        //判断手机号有没有注册过
        TAdmin admin = adminService.selectByPhone(phone);
        if(!Objects.isNull(admin)){
            return Result.bulid(ConstantEnum.ERROR).setResult("该手机号已注册过");
        }
        //发送消息把用户传进来的手机号发送过去到那边调阿里大于接口发送短信
        rocketMQTemplate.convertAndSend("phone-topic",phone);
        return Result.bulid(ConstantEnum.SUCCESS).setResult("发送成功");
    }
    @ApiOperation(value = "前台用户注册功能")
    @ApiImplicitParams({
            @ApiImplicitParam(name="username",value = "用户名",required = true,paramType = "query"),
            @ApiImplicitParam(name="password",value = "密码",required = true,paramType = "query"),
            @ApiImplicitParam(name="phone",value = "手机号",required = true,paramType = "query"),
            @ApiImplicitParam(name="code",value = "验证码",required = true,paramType = "query"),
            @ApiImplicitParam(name="adminAddress",value = "用户地址",required = true,paramType = "query"),
            @ApiImplicitParam(name="email",value = "用户email",required = true,paramType = "query"),
            @ApiImplicitParam(name="headSculpture",value = "用户头像",required = true,paramType = "query"),
            @ApiImplicitParam(name="sex",value = "性别",required = true,paramType = "query"),
            @ApiImplicitParam(name="nickName",value = "用户真实姓名",required = true,paramType = "query"),
            @ApiImplicitParam(name="idNumber",value = "用户身份证号码",required = true,paramType = "query"),
            @ApiImplicitParam(name="birthday",value = "用户生日",required = true,paramType = "query")
    })
    @PostMapping(value="/register")
    public Result register(TAdmin admin,String code){
        //序列化  只支持 string  hash 类型
        redisTemplate.setValueSerializer(new StringRedisSerializer());

        //获取redis存储的短信和用户填的短信进行对比
        String code1 = redisTemplate.boundHashOps("phone").get(admin.getPhone()).toString();
        if (!code.equals(code1)){
            return Result.bulid(ConstantEnum.ERROR).setResult("验证码不正确");
        }
        //根据用户名去查询用户表,判断用户名是否重复
        TAdmin admin1 = adminService.selectUserByUserName(admin.getUsername());
        if(!Objects.isNull(admin1)){
            return Result.bulid(ConstantEnum.ERROR).setResult("用户名已存在");
        }
        String salt = ShiroUtils.generateSalt(6);
        admin.setSalt(salt);
        String md5 = ShiroUtils.encryptPassword("MD5", admin.getPassword(), salt, 3);
        //String imgurl = upload(myFile);
        admin.setPassword(md5);
        admin.setStatus(1);//账号状况
        admin.setSourceType(1);//会员等级
        admin.setPoints(0);//积分
        admin.setCreated(new Date());//创建日期
       //admin.setHeadSculpture(imgurl);//头像
        admin.setCreateTime(new Date());
        admin.setUpdateTime(new Date());
        boolean b = adminService.save(admin);
        if (b){
            return Result.bulid(ConstantEnum.SUCCESS).setResult("注册成功");
        }
        return Result.bulid(ConstantEnum.ERROR);
    }

    @ApiOperation(value = "前台用户登录功能")
    @ApiImplicitParams({
            @ApiImplicitParam(name="username",value = "用户名",required = true,paramType = "query"),
            @ApiImplicitParam(name="password",value = "密码",required = true,paramType = "query")
    })
    @PostMapping("login")
    public Result login(@RequestParam("username") String username, @RequestParam("password") String password){
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken toke = new UsernamePasswordToken(username, password);
        try {
            subject.login(toke);
        } catch (UnknownAccountException e) {
            System.out.println("用户名不存在");
            return Result.bulid(ConstantEnum.ERROR).setResult("用户名不存在");
        }catch (IncorrectCredentialsException e){
            System.out.println("密码错误");
            return Result.bulid(ConstantEnum.ERROR).setResult("密码错误");
        }catch (LoginException e){
            System.out.println("状态异常");
            return Result.bulid(ConstantEnum.ERROR).setResult("状态异常");
        }
        TAdmin tAdmin = (TAdmin) subject.getPrincipal();
        //随机生产的key
        String token = UUID.randomUUID().toString();
        //序列化  只支持 string  hash 类型
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        String s = JSON.toJSONString(tAdmin);
        redisTemplate.boundValueOps(token).set(s);
        redisTemplate.boundValueOps(token).expire(30, TimeUnit.MINUTES);
        return Result.bulid(ConstantEnum.SUCCESS).setResult(token);
    }

    @ApiOperation(value = "图片上传")
    @PostMapping(value = "/upload",headers="content-type=multipart/form-data")
    public Result upload(@ApiParam(name = "image",value = "图片",required = true)MultipartFile image){
        // yourEndpoint填写Bucket所在地域对应的Endpoint。以华东1（杭州）为例，Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
        String http = "http://";
        String bucketName = "dongdongshop-hqq";
        String endpoint = "oss-cn-beijing.aliyuncs.com";
        // 阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维，请登录RAM控制台创建RAM用户。
        String accessKeyId = "LTAI5tKqSkBxTE5BbYcfHkMg";
        String accessKeySecret = "SDozOgebvZBF5sKF1yupJhNi39Rdzs";

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

        // 填写字符串。
        // String content = "Hello OSS";
        //把文件变成流
        InputStream inputStream = null;
        try {
            inputStream = image.getInputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        String originalFilename = image.getOriginalFilename();

        // 创建PutObjectRequest对象。
        // 依次填写Bucket名称（例如examplebucket）和Object完整路径（例如exampledir/exampleobject.txt）。Object完整路径中不能包含Bucket名称。
        PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, originalFilename,inputStream);

        // 如果需要上传时设置存储类型和访问权限，请参考以下示例代码。
        // ObjectMetadata metadata = new ObjectMetadata();
        // metadata.setHeader(OSSHeaders.OSS_STORAGE_CLASS, StorageClass.Standard.toString());
        // metadata.setObjectAcl(CannedAccessControlList.Private);
        // putObjectRequest.setMetadata(metadata);

        // 上传字符串。
        ossClient.putObject(putObjectRequest);

        // 关闭OSSClient。
        ossClient.shutdown();
        return Result.bulid(ConstantEnum.SUCCESS).setResult(http + bucketName + "." + endpoint + "/" + originalFilename);
    }

    @ApiOperation(value = "查询")
    @GetMapping
    public Result getInfoIdBy(){
        List<TAdmin> list = adminMapper.selectList(null);
        ArrayList list1 = new ArrayList();
        for (TAdmin tAdmin : list) {
            list1.add(tAdmin.getId());
        }
        return Result.bulid(ConstantEnum.SUCCESS).setResult(list1);
    }

    @ApiOperation(value = "根据用户主键查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name="id",value = "admin表的主键Id",required = true,paramType = "query")
    })
    @PostMapping("findAllAdminById")
    public Result findAllAdminById(Long id){
        TAdmin admin=adminMapper.selectById(id);
        return Result.bulid(ConstantEnum.SUCCESS).setResult(admin);
    }
}
